package org.example.springbootrabbitmq.confirm;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * @description: 发布确认相关模拟代码  消息确认以及消息回退
 * @author: guodf
 * @date: 2024/02/19 13:56
 **/
@Slf4j
@Component
public class MyCallBack implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {

    /**
     * 注入rabbitmqTemplate
     */
    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 为使当前自定义回调生效，需要注入到template中
     */
    @PostConstruct
    public void init(){
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnCallback(this);
    }

    /**
     * 该方法是针对交换机的确认消息回调接口
     * 只有当交换机不可达的情况下才会监控到丢了的消息
     * 但是如果交换机正常，队列或者路由出了问题，那么就会导致消息丢失
     * 此时，需要另一个功能：消息回退（针对的是队列或者路由Mandatory）
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean b, String s) {
        String id = correlationData!=null ? correlationData.getId() : "";
        if(b){
            System.out.println("消息发到交换机成功，id为：" + id);
        }else{
            System.out.println("消息发到交换机失败，id为：" + id);
        }
    }


    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        log.error("消息{},被交换机{}退回，退回原因：{},路由key:{}",
                message.toString(), exchange, replyText, routingKey);
    }
}
